#include "line_protocol_parser.h"
#include "exceptions.h"

#include <sstream>
#include <algorithm>

namespace kwdb {

LineProtocolParser::LineProtocolParser() {
    initializePatterns();
}

DataPoint LineProtocolParser::parse(const std::string& lineProtocol) {
    if (!isValid(lineProtocol)) {
        throw ParseException("无效的Line Protocol格式: " + lineProtocol);
    }
    
    try {
        // 分割measurement+tags, fields, timestamp
        std::vector<std::string> parts = splitString(lineProtocol, ' ');
        if (parts.size() < 2) {
            throw ParseException("Line Protocol格式错误，缺少fields部分");
        }
        
        std::string measurementTags = parts[0];
        std::string fields = parts[1];
        std::string timestamp = parts.size() > 2 ? parts[2] : "";
        
        // 解析measurement和tags
        auto [measurement, tags] = parseMeasurementAndTags(measurementTags);
        
        // 解析fields
        std::map<std::string, std::string> fieldsMap = parseFields(fields);
        
        // 解析时间戳
        int64_t timestampMs = timestamp.empty() ? 
            std::chrono::duration_cast<std::chrono::milliseconds>(
                std::chrono::system_clock::now().time_since_epoch()).count() :
            parseTimestamp(timestamp);
        
        // 创建DataPoint
        DataPoint dataPoint(measurement, timestampMs);
        
        // 添加tags
        for (const auto& [key, value] : tags) {
            dataPoint.addTag(key, value);
        }
        
        // 添加fields
        for (const auto& [key, value] : fieldsMap) {
            dataPoint.addField(key, value);
        }
        
        return dataPoint;
        
    } catch (const std::exception& e) {
        throw ParseException("Line Protocol解析失败: " + std::string(e.what()));
    }
}

std::string LineProtocolParser::toLineProtocol(const DataPoint& dataPoint) {
    return dataPoint.toLineProtocol();
}

std::vector<DataPoint> LineProtocolParser::parseBatch(const std::vector<std::string>& lineProtocols) {
    std::vector<DataPoint> dataPoints;
    dataPoints.reserve(lineProtocols.size());
    
    for (const auto& lineProtocol : lineProtocols) {
        try {
            dataPoints.push_back(parse(lineProtocol));
        } catch (const std::exception& e) {
            // 记录错误但继续处理其他数据
            // 这里可以添加日志记录
        }
    }
    
    return dataPoints;
}

std::vector<std::string> LineProtocolParser::toLineProtocolBatch(const std::vector<DataPoint>& dataPoints) {
    std::vector<std::string> lineProtocols;
    lineProtocols.reserve(dataPoints.size());
    
    for (const auto& dataPoint : dataPoints) {
        lineProtocols.push_back(toLineProtocol(dataPoint));
    }
    
    return lineProtocols;
}

bool LineProtocolParser::isValid(const std::string& lineProtocol) {
    if (lineProtocol.empty()) {
        return false;
    }
    
    // 基本格式检查：measurement[,tags] fields [timestamp]
    std::vector<std::string> parts = splitString(lineProtocol, ' ');
    if (parts.size() < 2) {
        return false;
    }
    
    // 检查measurement部分
    std::string measurementTags = parts[0];
    if (measurementTags.empty()) {
        return false;
    }
    
    // 检查fields部分
    std::string fields = parts[1];
    if (fields.empty()) {
        return false;
    }
    
    return true;
}

void LineProtocolParser::initializePatterns() {
    // 初始化正则表达式模式
    // 这里可以根据需要添加更复杂的模式匹配
}

std::pair<std::string, std::map<std::string, std::string>> LineProtocolParser::parseMeasurementAndTags(const std::string& measurementTags) {
    std::string measurement;
    std::map<std::string, std::string> tags;
    
    size_t commaPos = measurementTags.find(',');
    if (commaPos == std::string::npos) {
        // 没有tags
        measurement = measurementTags;
    } else {
        // 有tags
        measurement = measurementTags.substr(0, commaPos);
        std::string tagsStr = measurementTags.substr(commaPos + 1);
        
        // 解析tags
        std::vector<std::string> tagPairs = splitString(tagsStr, ',');
        for (const auto& tagPair : tagPairs) {
            size_t equalPos = tagPair.find('=');
            if (equalPos != std::string::npos) {
                std::string key = trimString(tagPair.substr(0, equalPos));
                std::string value = trimString(tagPair.substr(equalPos + 1));
                tags[key] = value;
            }
        }
    }
    
    return {measurement, tags};
}

std::map<std::string, std::string> LineProtocolParser::parseFields(const std::string& fieldsStr) {
    std::map<std::string, std::string> fields;
    
    std::vector<std::string> fieldPairs = splitString(fieldsStr, ',');
    for (const auto& fieldPair : fieldPairs) {
        size_t equalPos = fieldPair.find('=');
        if (equalPos != std::string::npos) {
            std::string key = trimString(fieldPair.substr(0, equalPos));
            std::string value = trimString(fieldPair.substr(equalPos + 1));
            fields[key] = parseFieldValue(value);
        }
    }
    
    return fields;
}

int64_t LineProtocolParser::parseTimestamp(const std::string& timestampStr) {
    try {
        int64_t timestamp = std::stoll(timestampStr);
        
        // 判断时间戳单位（秒、毫秒、微秒、纳秒）
        if (timestampStr.length() <= 10) {
            // 秒
            return timestamp * 1000;
        } else if (timestampStr.length() <= 13) {
            // 毫秒
            return timestamp;
        } else if (timestampStr.length() <= 16) {
            // 微秒
            return timestamp / 1000;
        } else {
            // 纳秒
            return timestamp / 1000000;
        }
    } catch (const std::exception& e) {
        throw ParseException("时间戳解析失败: " + std::string(e.what()));
    }
}

std::string LineProtocolParser::escapeString(const std::string& str) {
    std::string result = str;
    
    // 转义特殊字符
    size_t pos = 0;
    while ((pos = result.find(",", pos)) != std::string::npos) {
        result.replace(pos, 1, "\\,");
        pos += 2;
    }
    
    pos = 0;
    while ((pos = result.find(" ", pos)) != std::string::npos) {
        result.replace(pos, 1, "\\ ");
        pos += 2;
    }
    
    pos = 0;
    while ((pos = result.find("=", pos)) != std::string::npos) {
        result.replace(pos, 1, "\\=");
        pos += 2;
    }
    
    return result;
}

std::string LineProtocolParser::unescapeString(const std::string& str) {
    std::string result = str;
    
    // 反转义特殊字符
    size_t pos = 0;
    while ((pos = result.find("\\,", pos)) != std::string::npos) {
        result.replace(pos, 2, ",");
        pos += 1;
    }
    
    pos = 0;
    while ((pos = result.find("\\ ", pos)) != std::string::npos) {
        result.replace(pos, 2, " ");
        pos += 1;
    }
    
    pos = 0;
    while ((pos = result.find("\\=", pos)) != std::string::npos) {
        result.replace(pos, 2, "=");
        pos += 1;
    }
    
    return result;
}

std::string LineProtocolParser::parseFieldValue(const std::string& valueStr) {
    if (valueStr.empty()) {
        return "";
    }
    
    // 处理字符串值（用引号包围）
    if (valueStr.front() == '"' && valueStr.back() == '"') {
        return unescapeString(valueStr.substr(1, valueStr.length() - 2));
    }
    
    // 处理数值和布尔值
    return valueStr;
}

std::string LineProtocolParser::formatFieldValue(const std::string& value) {
    // 检查是否为数值或布尔值
    if (value == "true" || value == "false" || 
        (value.find_first_not_of("0123456789.-") == std::string::npos)) {
        return value;
    }
    
    // 字符串值需要转义
    return "\"" + escapeString(value) + "\"";
}

std::vector<std::string> LineProtocolParser::splitString(const std::string& str, char delimiter) {
    std::vector<std::string> result;
    std::stringstream ss(str);
    std::string item;
    
    while (std::getline(ss, item, delimiter)) {
        result.push_back(item);
    }
    
    return result;
}

std::string LineProtocolParser::trimString(const std::string& str) {
    size_t start = str.find_first_not_of(" \t\n\r");
    if (start == std::string::npos) {
        return "";
    }
    
    size_t end = str.find_last_not_of(" \t\n\r");
    return str.substr(start, end - start + 1);
}

} // namespace kwdb
